package util

import (
	"bytes"
	"compress/flate"
	"compress/gzip"
	"encoding/base64"
	"fmt"
	"github.com/disintegration/imaging"
	"image"
	"image/jpeg"
	"image/png"
	"log"
	"os"
	"strconv"
)

var IsCompress = true

func CreateCode() (string, string, string, int, int) {
	//生成随机数
	nums := 1
	//nums := GetRandInt(10)
	if nums == 0 {
		nums = 1
	}
	fmt.Println("num----", nums)
	imageId := GetUuid()
	f, _ := os.Open("./util/captcha/" + strconv.Itoa(nums) + ".jpg")
	//获取随机x坐标
	imageRandX := 150
	if imageRandX < 132 {
		imageRandX += 132
	}
	//获取随机y坐标
	imageRandY := 150
	if imageRandY < 65 {
		imageRandY += 65
	}
	//转化为image对象
	m, err := jpeg.Decode(f)
	if err != nil {
		panic(err)
	}
	//设置截取的最大坐标值和最小坐标值
	maxPotion := image.Point{
		X: imageRandX,
		Y: imageRandY,
	}
	minPotion := image.Point{
		X: imageRandX - 65,
		Y: imageRandY - 65,
	}
	subimg := image.Rectangle{
		Max: maxPotion,
		Min: minPotion,
	}
	//f, err = os.Create(fmt.Sprintf("./util/captcha/code/%sscreenshot.jpeg", imageId))
	//defer f.Close()
	//截取图像
	data := imaging.Crop(m, subimg)
	var buf bytes.Buffer
	err = imaging.Encode(&buf, data, imaging.JPEG, imaging.JPEGQuality(40))
	//err = imaging.Encode(&buf, data, imaging.PNG, imaging.PNGCompressionLevel(png.BestCompression))
	//err = png.Encode(&buf, data)
	if err != nil {
		log.Fatal(err)
	}

	// 将PNG编码流转换为Base64字符串
	base64Str := base64.StdEncoding.EncodeToString(buf.Bytes())
	var base64CutImgStr string
	// 输出Base64字符串
	if IsCompress {
		base64CutImgByt, _ := GzipEncode([]byte(fmt.Sprintf("data:image/jpeg;base64," + base64Str)))
		base64CutImgStr = string(base64CutImgByt)
	} else {
		base64CutImgStr = fmt.Sprintf("data:image/jpeg;base64," + base64Str)
	}

	//设置遮罩
	base64BgImgStr := createCodeImg("./util/captcha/"+strconv.Itoa(nums)+".jpg", minPotion)
	return base64CutImgStr, base64BgImgStr, imageId, imageRandX, imageRandY
}
func createCodeImg(path string, minPotion image.Point) (base64ImgStr string) {
	bg, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	maskFile, err := os.Open("./util/captcha/mask.png")
	if err != nil {
		panic(err)
	}
	bgimg, err := jpeg.Decode(bg)
	maskimg, err := png.Decode(maskFile)
	data := imaging.Overlay(bgimg, maskimg, minPotion, 1.0)
	//f, err := os.Create("./util/captcha/code/" + imageId + ".jpeg")
	//defer f.Close()
	//jpeg.Encode(f, data, nil)
	var buf bytes.Buffer
	err = imaging.Encode(&buf, data, imaging.JPEG, imaging.JPEGQuality(40))
	//err = imaging.Encode(&buf, data, imaging.PNG, imaging.PNGCompressionLevel(png.BestCompression))
	//err = png.Encode(&buf, data)
	if err != nil {
		log.Fatal(err)
	}

	// 将PNG编码流转换为Base64字符串
	base64Str := base64.StdEncoding.EncodeToString(buf.Bytes())
	if IsCompress {
		base64ImgStrByt, _ := GzipEncode([]byte(fmt.Sprintf("data:image/jpeg;base64," + base64Str)))
		base64ImgStr = string(base64ImgStrByt)
	} else {
		base64ImgStr = fmt.Sprintf("data:image/jpeg;base64," + base64Str)
	}
	return
}

func GzipEncode(input []byte) ([]byte, error) {
	// 创建一个新的 byte 输出流
	var buf bytes.Buffer
	// 创建一个新的 gzip 输出流

	//NoCompression      = flate.NoCompression      // 不压缩
	//BestSpeed          = flate.BestSpeed          // 最快速度
	//BestCompression    = flate.BestCompression    // 最佳压缩比
	//DefaultCompression = flate.DefaultCompression // 默认压缩比
	//gzip.NewWriterLevel()
	gzipWriter, _ := gzip.NewWriterLevel(&buf, flate.BestCompression)
	//gzipWriter := gzip.NewWriter(&buf)
	// 将 input byte 数组写入到此输出流中
	_, err := gzipWriter.Write(input)
	if err != nil {
		_ = gzipWriter.Close()
		return nil, err
	}
	if err := gzipWriter.Close(); err != nil {
		return nil, err
	}
	// 返回压缩后的 bytes 数组
	return buf.Bytes(), nil
}
